/////////////////////////////////////////////////////////////////////////////
/*/	
*	Creator:		Joshua C. Rouzer
*	Title:			
*	Last Edited:	06/11/2013
*	Summary:		
/*/
/////////////////////////////////////////////////////////////////////////////
#include "Team.h"
#include "EventManager.h"
#include "LevelManager.h"
#include "EntityManager.h"
#include "Waypoint.h"
#include "CSGD_TextureManager.h"
#include "Economy.h"
/////////////////////////////////////////////////////////////////////////////
// Function		: 
// Notes		: 
/////////////////////////////////////////////////////////////////////////////
CTeam::CTeam( bool TeamOne ){
	CEventManager::GetInstance()->RegisterListener( "NEW_WAYPOINT1", this );
	CEventManager::GetInstance()->RegisterListener( "NEW_WAYPOINT2", this );
	CEventManager::GetInstance()->RegisterListener( "NEW_WAYPOINT3", this );

	m_cPlayer = new CPlayerShip(TeamOne);
	m_cBase = new CBase(TeamOne);

	CEntityManager::GetInstance()->AddEntity(m_cPlayer);
	CEntityManager::GetInstance()->AddEntity(m_cBase);

	CEconomy::GetInstance()->AddPlayer(m_cPlayer);
}
/////////////////////////////////////////////////////////////////////////////
// Function		: 
// Notes		: 
/////////////////////////////////////////////////////////////////////////////
CTeam::~CTeam(){
	m_vPath1Units.clear();
	m_vPath2Units.clear();
	m_vPath3Units.clear();

	CEventManager::GetInstance()->UnregisterListener( "NEW_WAYPOINT1", this );
	CEventManager::GetInstance()->UnregisterListener( "NEW_WAYPOINT2", this );
	CEventManager::GetInstance()->UnregisterListener( "NEW_WAYPOINT3", this );

	CEconomy::GetInstance()->RemovePlayer( m_cPlayer );
}

/////////////////////////////////////////////////////////////////////////////
// Function		: Updates all the units of the team
// Parameters	: fDT - elapsed time between frames 
// Notes		: 
/////////////////////////////////////////////////////////////////////////////
void CTeam::Update( float fDT ){
	//// Update ship
	//m_cPlayer->Update( fDT );

	//// Update units
	//for( unsigned int i = 0; i < m_vPath1Units.size(); ++i ){
	//	m_vPath1Units[i]->Update( fDT );
	//}

	//for( unsigned int i = 0; i < m_vPath2Units.size(); ++i ){
	//	m_vPath2Units[i]->Update( fDT );
	//}

	//for( unsigned int i = 0; i < m_vPath3Units.size(); ++i ){
	//	m_vPath3Units[i]->Update( fDT );
	//}
}

/////////////////////////////////////////////////////////////////////////////
// Function		: Renders all the units
// Parameters	: 
// Notes		: 
/////////////////////////////////////////////////////////////////////////////
void CTeam::Render( void ){
	// Render Ship
	m_cPlayer->Render();

	// Render Units
	for( unsigned int i = 0; i < m_vPath1Units.size(); ++i ){
		m_vPath1Units[i]->Render();
	}

	for( unsigned int i = 0; i < m_vPath2Units.size(); ++i ){
		m_vPath2Units[i]->Render();
	}

	for( unsigned int i = 0; i < m_vPath3Units.size(); ++i ){
		m_vPath3Units[i]->Render();
	}
}

/////////////////////////////////////////////////////////////////////////////
// Function		: 
// Parameters	: path - 
//					unit - 
// Notes		: 
/////////////////////////////////////////////////////////////////////////////
void CTeam::AddUnit(int path, CBaseUnit* unit){
	if( path == 1 )
		m_vPath1Units.push_back( unit );
	else if( path == 2 )
		m_vPath2Units.push_back( unit );
	else if( path == 3 )
		m_vPath3Units.push_back( unit );
}
/////////////////////////////////////////////////////////////////////////////
// Function		: 
// Parameters	: path - 
//					unit - 
// Notes		: 
/////////////////////////////////////////////////////////////////////////////
void CTeam::RemoveUnit(int path, CBaseUnit* unit){
	if(unit == nullptr)
		return;

	switch (path)
	{
	case 1:
		for (vector<CBaseUnit*>::iterator iter = GetPath1Units().begin();
			iter != GetPath1Units().end(); ++iter)
		{
			if( (*iter) == unit )
			{
				GetPath1Units().erase( iter );
				break;
			}
		}
		break;
	case 2:
		for (vector<CBaseUnit*>::iterator iter = GetPath2Units().begin();
			iter != GetPath2Units().end(); ++iter)
		{
			if( (*iter) == unit )
			{
				GetPath2Units().erase( iter );
				break;
			}
		}
		break;
	case 3:
		for (vector<CBaseUnit*>::iterator iter = GetPath3Units().begin();
			iter != GetPath3Units().end(); ++iter)
		{
			if( (*iter) == unit )
			{
				GetPath3Units().erase( iter );
				break;
			}
		}
		break;
	}


}

/////////////////////////////////////////////////////////////////////////////
// Function		: 
// Parameters	: path - 
//					unit - 
// Notes		: 
/////////////////////////////////////////////////////////////////////////////
void CTeam::AddBarricade(int path, CDefenseStruct* barr){
	if( path == 1 )
		m_vPath1Gates.push_back( barr );
	else if( path == 2 )
		m_vPath2Gates.push_back( barr );
	else if( path == 3 )
		m_vPath3Gates.push_back( barr );
}
/////////////////////////////////////////////////////////////////////////////
// Function		: 
// Parameters	: path - 
//					unit - 
// Notes		: 
/////////////////////////////////////////////////////////////////////////////
void CTeam::RemoveBarricade(int path, CDefenseStruct* barr){
	if(barr == nullptr)
		return;

	switch (path)
	{
	case 1:
		for (vector<CDefenseStruct*>::iterator iter = GetPath1Gates().begin();
			iter != GetPath1Gates().end(); ++iter)
		{
			if( (*iter) == barr )
			{
				GetPath1Gates().erase( iter );
				break;
			}
		}
		break;
	case 2:
		for (vector<CDefenseStruct*>::iterator iter = GetPath2Gates().begin();
			iter != GetPath2Gates().end(); ++iter)
		{
			if( (*iter) == barr )
			{
				GetPath2Gates().erase( iter );
				break;
			}
		}
		break;
	case 3:
		for (vector<CDefenseStruct*>::iterator iter = GetPath3Gates().begin();
			iter != GetPath3Gates().end(); ++iter)
		{
			if( (*iter) == barr )
			{
				GetPath3Gates().erase( iter );
				break;
			}
		}
		break;
	}


}

/////////////////////////////////////////////////////////////////////////////
// Function		: 
// Parameters	: change - 
// Notes		: 
/////////////////////////////////////////////////////////////////////////////
void CTeam::ModifyScore(int change){
	m_nScore += change;
}

/////////////////////////////////////////////////////////////////////////////
// Function		: 
// Parameters	: 
// Notes		: 
/////////////////////////////////////////////////////////////////////////////
void CTeam::HandleEvent( Event* pEvent ){
	// type of event
	if( pEvent->GetEventIDtype() == "NEW_WAYPOINT1" )
	{
		// which unit is it for?
		for( unsigned int i = 0; i < GetPath1Units().size(); ++i )
		{
			if( pEvent->GetListener() == GetPath1Units()[i] )
			{
				// Finds current waypoint
				//for( unsigned int j = 0; j < CLevelManager::GetInstance()->GetCurrLevel()->GetPath1()->GetWaypoints().size(); ++j )
				//{
				//	CWaypoint* waypoint = CLevelManager::GetInstance()->GetCurrLevel()->GetPath1()->GetWaypoints()[i];
				//	if( waypoint == (CWaypoint*)pEvent->GetSender() )
				//	{
				//		// Assigns next waypoint depending on which team they are on
				//		if( GetTeamID() == 1 && j + 1 < CLevelManager::GetInstance()->GetCurrLevel()->GetPath1()->GetWaypoints().size() )
				//			GetPath1Units()[i]->SetWaypoint( CLevelManager::GetInstance()->GetCurrLevel()->GetPath1()->GetWaypoints()[j+1] );
				//		else if( j - 1 >= 0 )
				//			GetPath1Units()[i]->SetWaypoint( CLevelManager::GetInstance()->GetCurrLevel()->GetPath1()->GetWaypoints()[j-1] );
				//		break;
				//	}
				//}
				// Assigns next waypoint depending on which team they are on
				CWaypoint* pt = (CWaypoint*)pEvent->GetParameter();
				GetPath1Units()[i]->SetWaypoint( pt );
				break;
			}
		}
	}

	// type of event
	if( pEvent->GetEventIDtype() == "NEW_WAYPOINT2" )
	{
		// which unit is it for?
		for( unsigned int i = 0; i < GetPath2Units().size(); ++i )
		{
			if( pEvent->GetListener() == GetPath2Units()[i] )
			{
				// Assigns next waypoint depending on which team they are on
				/*unsigned int* pt = (unsigned int*)pEvent->GetSender();
				unsigned int j = *pt;
				if( GetTeamID() == 1 && j + 1 < CLevelManager::GetInstance()->GetCurrLevel()->GetPath2()->GetWaypoints().size() )
					GetPath2Units()[i]->SetWaypoint( CLevelManager::GetInstance()->GetCurrLevel()->GetPath2()->GetWaypoints()[j+1] );
				else if( GetTeamID() != 1 && (int)j - 1 >= 0 )
					GetPath2Units()[i]->SetWaypoint( CLevelManager::GetInstance()->GetCurrLevel()->GetPath2()->GetWaypoints()[j-1] );
				delete pt;*/
				CWaypoint* pt = (CWaypoint*)pEvent->GetParameter();
				GetPath2Units()[i]->SetWaypoint( pt );
				break;
			}
		}
	}

	// type of event
	if( pEvent->GetEventIDtype() == "NEW_WAYPOINT3" )
	{
		// which unit is it for?
		for( unsigned int i = 0; i < GetPath3Units().size(); ++i )
		{
			if( pEvent->GetListener() == GetPath3Units()[i] )
			{
				// Assigns next waypoint depending on which team they are on
				CWaypoint* pt = (CWaypoint*)pEvent->GetParameter();
				GetPath3Units()[i]->SetWaypoint( pt );
				break;
			}
		}
	}
}

/////////////////////////////////////////////////////////////////////////////
// Function		: 
// Parameters	: ID - 
// Notes		: 
/////////////////////////////////////////////////////////////////////////////
void CTeam::SetTeamID(int ID){
	m_nTeamID = ID;
}
/////////////////////////////////////////////////////////////////////////////
// Function		: 
// Return		: 
// Notes		: 
/////////////////////////////////////////////////////////////////////////////
int CTeam::GetTeamID(){
	return m_nTeamID;
}
/////////////////////////////////////////////////////////////////////////////
// Function		: 
// Parameters	: player - 
// Notes		: 
/////////////////////////////////////////////////////////////////////////////
void CTeam::SetPlayerShip(CPlayerShip* player){
	m_cPlayer = player;
}
/////////////////////////////////////////////////////////////////////////////
// Function		: 
// Return		: 
// Notes		: 
/////////////////////////////////////////////////////////////////////////////
CPlayerShip* CTeam::GetPlayerShip(){
	return m_cPlayer;
}
/////////////////////////////////////////////////////////////////////////////
// Function		: 
// Return		: 
// Notes		: 
/////////////////////////////////////////////////////////////////////////////
void CTeam::SetBase(CBase* base){
	m_cBase = base;
}
/////////////////////////////////////////////////////////////////////////////
// Function		: 
// Return		: 
// Notes		: 
/////////////////////////////////////////////////////////////////////////////
CBase* CTeam::GetBase(){
	return m_cBase;
}
/////////////////////////////////////////////////////////////////////////////
// Function		: 
// Parameters	: scheme - 
// Notes		: 
/////////////////////////////////////////////////////////////////////////////
void CTeam::SetControlScheme(int scheme){
	m_nControlScheme = scheme;
}
/////////////////////////////////////////////////////////////////////////////
// Function		: 
// Return		: 
// Notes		: 
/////////////////////////////////////////////////////////////////////////////
int CTeam::GetScore(){
	return m_nScore;
}

/////////////////////////////////////////////////////////////////////////////
// Function		: 
// Parameters	: AI - 
// Notes		: 
/////////////////////////////////////////////////////////////////////////////
void CTeam::SetIsAI(bool AI){
	m_bIsAI = AI;
}
/////////////////////////////////////////////////////////////////////////////
// Function		: 
// Return		: 
// Notes		: 
/////////////////////////////////////////////////////////////////////////////
bool CTeam::GetIsAI(){
	return m_bIsAI;
}

/////////////////////////////////////////////////////////////////////////////
// Function		: 
// Return		: 
// Notes		: 
/////////////////////////////////////////////////////////////////////////////
std::vector<CBaseUnit*>& CTeam::GetPath1Units( void ){
	return m_vPath1Units;
}
std::vector<CBaseUnit*>& CTeam::GetPath2Units( void ){
	return m_vPath2Units;
}
std::vector<CBaseUnit*>& CTeam::GetPath3Units( void ){
	return m_vPath3Units;
}

std::vector<CDefenseStruct*>& CTeam::GetPath1Gates( void ){
	return m_vPath1Gates;
}
std::vector<CDefenseStruct*>& CTeam::GetPath2Gates( void ){
	return m_vPath2Gates;
}
std::vector<CDefenseStruct*>& CTeam::GetPath3Gates( void ){
	return m_vPath3Gates;
}